// Copyright 2022 The Liquigo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package translate

import (
	"strings"

	config "gitee.com/west0207/liquigo/core/config"
	. "gitee.com/west0207/liquigo/core/log"
	utils "gitee.com/west0207/liquigo/core/utils"

	db "gitee.com/west0207/liquigo/core/db"

	etree "gitee.com/west0207/etree"
)

// 在changeSet的执行失败后，执行该changeSet的回滚标签
// rollbackEles []*etree.Element 回滚标签列表
func HandleRollback(dbConfig *config.DB, rollbackEles []*etree.Element) error {
	for i := 0; i < len(rollbackEles); i++ {
		childEles := rollbackEles[i].ChildElements()
		if len(childEles) > utils.INT_ZERO {
			if err := runRollbackEntityEles(dbConfig, childEles); err != nil {
				return err
			}
			continue
		}
		rollbackSql := rollbackEles[i].Text()
		if strings.Trim(rollbackSql, utils.BLANK_CHARS) != utils.EMPTY {
			if err := runRollbackSql(&rollbackSql); err != nil {
				return err
			}
		}
	}
	return nil
}

// 执行该回滚标签中的实体标签
// entityEles []*etree.Element 一个回滚标签中的实体标签列表
func runRollbackEntityEles(dbConfig *config.DB, entityEles []*etree.Element) error {
	var builder strings.Builder
	entityLen := len(entityEles)
	builder.Grow(entityLen * utils.ONE_THOUSAND)

	for i := 0; i < entityLen; i++ {
		entityEleSql, err := GetSql(dbConfig, entityEles[i])
		if err != nil {
			// 翻译entityEle为sql语句失败
			Sug.Errorf("Failed to translate rollback.entityEle into SQL statement, err: %v", err)
			return err
		}
		utils.StringAppender(&builder, entityEleSql)
	}
	rollbackSql := builder.String()
	if rollbackSql != utils.EMPTY {
		if err := runRollbackSql(&rollbackSql); err != nil {
			return err
		}
	}
	return nil
}

// 1 执行该回滚标签中的sql文本
// 2 执行该回滚标签中的实体标签解析后的sql文本
func runRollbackSql(rollbackSql *string) error {
	if _, err := db.Engine.Exec(*rollbackSql); err != nil {
		// 执行元数据库表sql语句失败
		Sug.Errorf("Failed to execute rollback SQL statement, err: %v", err)
		Sugf.Errorf("rollbackSql: \n%v", *rollbackSql)
		return err
	}
	return nil
}
